﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
using System.Reflection;

namespace Utility
{
	public static class EnumEX
	{
		struct EnumInfo
		{
			public string[] names;
			public string[] showNames;
			public Array values;
		}

		static Dictionary<Type, EnumInfo> enumInfos = new Dictionary<Type, EnumInfo> ();

		static EnumInfo GetInfo (Type type)
		{
			if (!enumInfos.TryGetValue (type, out var info))
			{
				info = new EnumInfo ();
				info.names = Enum.GetNames (type);
				info.values = Enum.GetValues (type);
				info.showNames = (from name in info.names
								  let member = type.GetField (name)
								  let att = member.GetCustomAttribute<ShowNameAttribute> ()
								  select att?.ShowName ?? name).ToArray ();

				enumInfos[type] = info;
			}
			return info;
		}

		public static string[] GetNames (Type type)
		{
			if (!type.IsEnum)
			{
				throw new Exception ("Type must be an enum type");
			}

			return GetInfo (type).names;
		}

		public static string[] GetNames<TEnum> () where TEnum : Enum
		{
			return GetNames (typeof (TEnum));
		}

		public static string[] GetShowNames (Type type)
		{
			if (!type.IsEnum)
			{
				throw new Exception ("Type must be an enum type");
			}

			return GetInfo (type).showNames;
		}

		public static string[] GetShowNames<TEnum> () where TEnum : Enum
		{
			return GetShowNames (typeof (TEnum));
		}


		public static Array GetValues (Type type)
		{
			if (!type.IsEnum)
			{
				throw new Exception ("Type must be an enum type");
			}

			return GetInfo (type).values;
		}

		public static TEnum[] GetValues<TEnum> () where TEnum : Enum
		{
			return (TEnum[])GetValues (typeof (TEnum));
		}
	}
}